Create Contract
Step 2: Create a Contract​
After obtaining the access token, use it to create a payment contract.
Endpoint​
POST /apps/api/contracts
Headers
-
Authorization: Bearer
{access_token}
Replace{access_token}with the token obtained from login (Step 1). -
Content-Type: application/json
Request Body​
{
"title": "Sell a property111",
"contractServiceType": "Product",
"BuyerParty": {
"platformRefId" : "USR_abc001", //Optional.
"phoneNumber": "966583944460", //Required if platformRefId is not provided
"firstName": "Buyer", //Required if platformRefId is not provided
"lastName": "Name", //Required if platformRefId is not provided
"KYC": //Optional.
{
"identity": "74325500958",
"dateOfBirth": "2000-01-01T10:27:39.889Z" //Optional.
}
},
"SellerParty": {
"platformRefId" : "USR_abc002", //Optional.
"phoneNumber": "966583944461", //Required if platformRefId is not provided
"firstName": "Seller", //Required if platformRefId is not provided
"lastName": "", //Required if platformRefId is not provided
"KYC": //Optional.
{
"identity": "5232210232",
"IBANNumber": "SA0380000000608010167519",
"dateOfBirth": "2000-01-01T10:27:39.889Z" //Optional.
}
},
"amount": 1000,
"description": "Extenal Iphone mobile",
"notes": "notes for mobile",
"reference": "12321",
"metaData": {
"metadata1": "1",
"metadata2": "2",
"metadata3": "",
"metadata4": ""
},
"callbackUrl": "https://yourdomain.com/usercart",
"Milestones": [
{
"Name": "milestone 1 name",
"Description": "milestone 1 description",
"Amount": 600,
"DueDate": "2026-12-20T10:00:00.000Z"
},
{
"Name": "milestone 2 name",
"Description": "milestone 2 description",
"Amount": 400,
"DueDate": "2026-12-31T09:35:30.369Z"
}
]
}
Field Descriptions​
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| title | string | Contract title | Required Example: "Sell a property111" |
| contractServiceType | string | Type of service for the contract | Required Expected Values: "Product", "Service" |
| BuyerParty | object (Party) | Buyer information | Required |
| SellerParty | object (Party) | Seller information | Required |
| amount | number | Contract amount | Required Example: 1000 |
| description | string | Contract description | Optional Example: "Extenal Iphone mobile" |
| notes | string | Additional notes | Optional Example: "notes for mobile" |
| reference | string | External reference identifier | Optional Example: "12321" |
| metaData | object (MetaData) | Custom key-value metadata | Optional |
| callbackUrl | string | Callback URL for contract events | Optional Example: "https://yourdomain.com/usercart" |
| Milestones | list of objects (Milestone) | Seperate contract into multiple milestones | Optional |
Party (BuyerParty / SellerParty)
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| platformRefId* | string | User identifier in wepay system | Optional |
| phoneNumber | string | Party phone number (including country code) | Required if platformRefId is not provided Example: "966583944460" |
| firstName | string | First name | Required if platformRefId is not provided Example: "Ahmad" |
| lastName | string | Last name | Required if platformRefId is not provided Example: "Ali" |
*platformRefId is optional in the request. It is a unique identifier across all parties in the system. It can be used to link the party to an existing user in your system or to store a reference for future lookups.
To get platformRefId, you can call the User Onboarding API to retrieve a user and obtain his platformRefId, if exists.
You can also choose to not provide platformRefId in the request, or just provide the party's phone number and name and WePay will try to find an existing user with the same phone number. If the user is a new one, it will be created automatically in the system and a new platformRefId will be generated for him, and will be returned in the response. You can then store this platformRefId in your system for future reference.
If you want to create a user in Wepay and get the platformRefId before creating a contract, you can use the User Creation API to create a new user and get his platformRefId, then use this platformRefId in the contract creation request.
Note: On contract creation, the seller receives an SMS with a KYC link to verify his identity.
Party (SellerParty)
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| kyc | object | kyc data for seller | Optional |
Kyc object
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| identity | string | Seller national id | Required |
| iBANNumber | string | Seller bank account IBAN | Required for seller |
| dateOfBirth | datetime | Seller date of birth | Optional |
MetaData
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| metadata1 | string | Custom metadata field | OptionalExample: "1" |
| metadata2 | string | Custom metadata field | OptionalExample: "2" |
| metadata3 | string | Custom metadata field | OptionalExample: "" |
| metadata4 | string | Custom metadata field | OptionalExample: "" |
Milestone
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| Name | string | Milestone name | Required OptionalExample: "milestone 1 name" |
| Description | string | Milestone Description | OptionalExample: "milestone 1 description" |
| Amount | Number | Milestone amount | Required OptionalExample: 600 Note: Must be lower than contract amount and the total of all milestones amounts must be equal to the contract amount |
| DueDate | string (date-time) | Contract creation timestamp (UTC) | Required Example: 2026-12-20T10:00:000Z |
Response:​
Result<ExternalCreateContractResponse>
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| succeeded | boolean | Indicates whether the request was successful | Required Example: true |
| message | string | Result message | Optional Example: "Contract created successfully" |
| errors | array of string | List of validation or business errors | Optional |
| data | object (ExternalCreateContractResponse) | Contract creation result data | Optional |
ExternalCreateContractResponse
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| contractId | string | Unique external contract identifier | Required Example: "c8f1a3c2-9d12-4c8b-9f0a-123456789abc" |
| status | string (ContractStatus) | Current contract status | Required Example: "Pending" |
| contractServiceType | string (ContractServiceType) | Type of contract service | Required Example: "Product" |
| checkoutUrl | string | Checkout URL for completing payment | Required Example: "https://integration.wepay-sa.com/checkout?token=encodedToken" The token is valid for 10 minutes. If expired, you need to request a new one by calling /apps/api/contracts/checkout |
| buyerParty | object (ExternalContractParty) | Buyer party details | Required |
| sellerParty | object (ExternalContractParty) | Seller party details | Required |
| reference | string | External reference identifier | Optional Nullable |
| metaData | object (ContractMetaData) | Custom metadata | Optional Nullable |
| milestones | array of Milestone | Contract milestones | Required |
| pricingLineItems | array of ExternalPriceLineItem | Pricing breakdown items | Required |
| createdDate | string (date-time) | Contract creation timestamp (UTC) | Required Example: 2024-01-15T10:30:00Z |
ExternalContractParty
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| platformRefId | string | User identifier in wepay | Required |
| firstName | string | First name | Required Example: "Ahmad" |
| lastName | string | Last name | Required Example: "Ali" |
| phoneNumber | string | Phone number including country code | Required Example: "966583944460" |
ContractMetaData
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| metadata1 | string | Custom metadata field | Optional |
| metadata2 | string | Custom metadata field | Optional |
| metadata3 | string | Custom metadata field | Optional |
| metadata4 | string | Custom metadata field | Optional |
Milestone
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| Id | number | Milestone identifier | Required Example: 13 |
| name | string | Milestone name | Required Example: "Delivery" |
| description | string | Milestone description | Optional |
| amount | number | Milestone amount | Required Example: 500 |
| dueDate | string (date-time) | Milestone due date (UTC) | Required Example: 2024-02-01T00:00:00Z |
| pricingLineItems | array of ExternalPriceLineItem | Pricing breakdown items | Required |
Milestone Validation Rules​
| Rule | Requirement |
|---|---|
| Total amounts | Must equal contract amount |
| Milestone amount | Must be > 0 |
| DueDate format | ISO 8601 UTC (with Z suffix) |
| Name | Required field |
| Description | Optional field |
Important: Milestone Amount Calculation​
Request Amount = Base contract amount
Response Amount = Base + all fees + taxes
Example:
- Request: 600 SAR (base)
- Response: 686.25 SAR (includes escrow fees, platform fees, VAT)
See PricingLineItems array for full breakdown.
ExternalPriceLineItem
| Field Name | Type | Description | Required / Notes / Example |
|---|---|---|---|
| lineType | string (PricingLineType) | Pricing line type | Required Example: "EscrowFee" |
| LineTypeDescription | string | Pricing line type description | Required |
| role | string (PricingRole) | Party responsible for the amount | Required Example: "Buyer" |
| RoleDescription | string | Role description | Required |
| amount | number | Amount value | Required Example: 50 |
| description | string | Pricing line description | Optional |
| order | integer | Display order | Required Example: 1 |
Example Request (cURL)​
curl -X POST "https://api.wepay.com.sa/apps/api/contracts" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "TEST Sell a property111",
"contractServiceType": "Product",
"BuyerParty": {
"phoneNumber": "966583944460",
"firstName": "Buyer",
"lastName": "Name aa"
},
"SellerParty": {
"phoneNumber": "966583944461",
"firstName": "Seller",
"lastName": ""
},
"amount": 1000,
"description": "TEST External Iphone mobile",
"notes": "notes for mobile",
"callbackurl": "http://localhost:3000/en/payment-success",
"Milestones": [
{
"Name": "milestone 1 name",
"Description": "milestone 1 description",
"Amount": 600,
"DueDate": "2026-12-20T10:00:00.000Z"
},
{
"Name": "milestone 2 name",
"Description": "milestone 2 description",
"Amount": 400,
"DueDate": "2026-12-31T09:35:30.369Z"
}
]
}'
Note: API uses camelCase for JSON responses:
- Request:
"Milestones"(PascalCase - C# convention) - Response:
"milestones"(camelCase - JSON convention)
DueDate Format: Always use UTC timezone
- Example:
"2026-12-20T10:00:00.000Z" - System converts to Saudi time (UTC+3) for display
Note: Milestones are read-only after contract creation.
Example Response​
{
"data": {
"contractId": "CNT-2601-00100003",
"status": "pending",
"contractServiceType": "product",
"checkoutUrl": "https://integration.welink-sa.com/checkout?token=RSGFF38PXVO....",
"buyerParty": {
"platformRefId": "USR_20260405152053_5487",
"firstName": "Buyer",
"lastName": "Name aa",
"phoneNumber": "966583944460"
},
"sellerParty": {
"platformRefId": "USR_20260405151029_7034",
"firstName": "Seller",
"lastName": "",
"phoneNumber": "966583944461"
},
"reference": "12321",
"metaData": {
"metadata1": "1",
"metadata2": "2",
"metadata3": "",
"metadata4": ""
},
"milestones": [
{
"Id": 12,
"Name": "milestone 1 name",
"Description": "milestone 1 description",
"DueDate": "2026-12-20T10:00:00.000Z",
"Amount": 686.25,
"PricingLineItems": [
{
"lineType": "contractAmount",
"role": "buyer",
"amount": 600,
"description": null,
"order": 1
},
{
"lineType": "escrowFee",
"role": "thirdParty",
"amount": 15.0,
"description": null,
"order": 2
},
{
"lineType": "escrowFeeTax",
"role": "thirdParty",
"amount": 2.25,
"description": null,
"order": 3
},
{
"lineType": "externalPlatformFee",
"role": "buyer",
"amount": 60.00,
"description": null,
"order": 4
},
{
"lineType": "externalPlatformFeeTax",
"role": "buyer",
"amount": 9.00,
"description": null,
"order": 5
},
{
"lineType": "netEscrowAmountToSeller",
"role": "seller",
"amount": 600,
"description": null,
"order": 6
}
]
},
{
"Id": 13,
"Name": "milestone 2 name",
"Description": "milestone 2 description",
"DueDate": "2026-12-31T09:35:30.369Z",
"Amount": 457.5,
"PricingLineItems": [
{
"lineType": "contractAmount",
"role": "buyer",
"amount": 400,
"description": null,
"order": 1
},
{
"lineType": "escrowFee",
"role": "thirdParty",
"amount": 10.00,
"description": null,
"order": 2
},
{
"lineType": "escrowFeeTax",
"role": "thirdParty",
"amount": 1.50,
"description": null,
"order": 3
},
{
"lineType": "externalPlatformFee",
"role": "buyer",
"amount": 40.00,
"description": null,
"order": 4
},
{
"lineType": "externalPlatformFeeTax",
"role": "buyer",
"amount": 6.00,
"description": null,
"order": 5
},
{
"lineType": "netEscrowAmountToSeller",
"role": "seller",
"amount": 400,
"description": null,
"order": 6
}
]
}
],
"pricingLineItems": [
{
"lineType": "contractAmount",
"role": "buyer",
"amount": 1000,
"description": null,
"order": 1
},
{
"lineType": "escrowFee",
"role": "thirdParty",
"amount": 25.0,
"description": null,
"order": 2
},
{
"lineType": "escrowFeeTax",
"role": "thirdParty",
"amount": 3.75,
"description": null,
"order": 3
},
{
"lineType": "externalPlatformFee",
"role": "buyer",
"amount": 100.0,
"description": null,
"order": 4
},
{
"lineType": "externalPlatformFeeTax",
"role": "buyer",
"amount": 15.0,
"description": null,
"order": 5
},
{
"lineType": "netEscrowAmountToSeller",
"role": "seller",
"amount": 1000,
"description": null,
"order": 6
}
],
"createdDate": "2026-01-25T10:28:10.4874015Z"
},
"message": "Contract created successfully.",
"status": 200,
"validationErrors": []
}